import * as React from 'react'
import { Input, Button, Table, Modal, message, Select, Form, DatePicker, Tooltip } from 'antd'
import { ExclamationCircleOutlined, DeleteOutlined, LockOutlined } from '@ant-design/icons';
import { Authority, User as _User, Role, Config } from '../../serve/interface';
import { ColumnsType } from 'antd/lib/table';
import locale from 'antd/es/date-picker/locale/zh_CN';
import moment from 'moment'
import { prompt } from '../components/prompt'
import JiraUserSelector from './sub/JiraUserSelector'

const FormItem = Form.Item

interface User extends _User {
    roleName?: string
}
const { confirm } = Modal;
const { Option } = Select

declare var __all_config__: Partial<Config>;
const { store } = __all_config__

const reg_password = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)\w{8,16}$/
const create_password = () => {
    const Cptl = String.fromCharCode(65 + Math.random() * 26)
    let password = ''
    do {
        password = Cptl + Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(36)
    } while (!reg_password.test(password))
    return password
}

export interface UserListProps {
    isShow?: boolean
    authorities?: Authority[]
    users?: User[]
    roles?: Role[]
    loginUser?: User
    addUser?: ({ name, password, nickname }) => Promise<void>
    delUser?: (userId: string | number) => Promise<void>
    updateUserRole?: ({ userId, roleId }) => Promise<void>
    updateUserLockIPs?: ({ userId, ips }) => Promise<void>
    updateUserExpires?: ({ userId, expires }) => Promise<void>
    resetPassword?: (userId: string | number, password: string) => Promise<void>
}
export interface UserListState {
    name: string
    password: string
    nickname: string
    password_confirm?: string
    keyWord: string,
    addUserModalShow: boolean,
    filteredInfo: object,
}

export default class UserList extends React.Component<UserListProps, UserListState> {
    constructor(props: UserListProps) {
        super(props)
        this.state = {
            name: '',
            password: '',
            password_confirm: '',
            nickname: '',
            keyWord: '',
            addUserModalShow: false,
            filteredInfo: null,
        }
    }

    render() {
        const { users = [], roles = [] } = this.props;
        let { name, nickname, password, password_confirm, keyWord,filteredInfo  } = this.state;
        filteredInfo = filteredInfo || {};
        let _users = users.map(item => {
            return {
                ...item,
                roleName: roles.find(role => role.id === item.roleId) ? roles.find(role => role.id === item.roleId).name : '',
                key: item.id
            }
        })
        let reg = new RegExp(keyWord)
        _users = _users.filter((i) => reg.test(i.name) || reg.test(i.nickname))

        let columns: ColumnsType<User> = [
            {
                title: 'ID',
                dataIndex: 'id',
                key: 'id'
            },
            {
                title: '用户名',
                dataIndex: 'name',
                key: 'name'
            },
            {
                title: '昵称',
                dataIndex: 'nickname',
                key: 'nickname'
            },
            {
                title: '角色',
                dataIndex: 'roleName',
                key: 'roleName',
                render: (text, data) => <div>
                    <div>
                        <Select allowClear={true} style={{ width: 125 }} placeholder="无用户角色" value={data.roleId} onChange={(e) => this.updateUserRole(e, data.id)}>
                            {roles.map(item => {
                                return <Option key={item.id} value={item.id}>{item.name}</Option>
                            })}
                        </Select>
                    </div>
                </div>,
                filters: roles.map(item => {
                    return { text: item.name, value: item.name }
                }),
                //   filteredValue: filteredInfo.roleName || null,
                  onFilter: (value, record) => record.roleName==value,
            },
        ]
        if (__all_config__.user_ip_lock) {
            columns.push({
                title: '准入IP',
                dataIndex: 'lock_ips',
                key: 'lock_ips',
                render: (text, data) =>
                    <Input
                        placeholder="输入IP，多个IP之间用英文逗号','分开"
                        defaultValue={data.lock_ips && data.lock_ips.join(',')}
                        onBlur={this.updateUserLockIPs(data.id)}
                        onPressEnter={this.updateUserLockIPs(data.id)}
                    />
            })
        }
        if (__all_config__.user_expires) {
            columns.push({
                title: '失效日期',
                dataIndex: 'expires',
                key: 'expires',
                render: (text, data) => <DatePicker placeholder="永久有效"
                    defaultValue={data.expires ? moment(+data.expires) : undefined}
                    locale={locale} showTime={{ format: 'HH:mm' }}
                    onChange={date => {
                        this.updateUserExpires(data.id)(date ? date.toDate().getTime() : 0)
                    }} />
            })
        }
        columns.push({
            title: '操作',
            align: 'center',
            dataIndex: 'opt',
            key: 'opt',
            render: (text, data) => <div>
                {!store.noAddUser && <Tooltip title="删除用户">
                    <Button type="link" onClick={(e) => this.delUser(data.id)}>
                        <DeleteOutlined  />
                    </Button>
                </Tooltip>}
                
                {store.usePasswordChange && <Tooltip title="重置用户密码">
                    <Button type="link" onClick={(e) => this.resetPassword(data.id)}>
                        <LockOutlined />
                    </Button>
                </Tooltip>}
            </div>
        })

        const formItemLayout = {
            labelCol: { span: 4 },
            wrapperCol: { span: 20 },
        }

        return <div>

            <div style={{ display: 'flex', margin: '20px 0' }}>
                <div style={{ marginRight: 16 }}>
                    <Input type="text" placeholder="请输入用户名或昵称" value={keyWord} onChange={(e) => this.changeValue(e, 'keyWord')} />
                </div>
                <div>
                    <Button type="primary" style={{ marginRight: 20 }}>
                        搜索
                    </Button>
                    {
                        !store.noAddUser &&
                        <Button type="primary" onClick={this.addUserModalOnShow}>
                            添加用户
                        </Button>
                    }
                </div>
            </div>

            <Table key="id" dataSource={_users} columns={columns} bordered size="small" />

            {store.apiRoot
                ? <Modal
                    title="添加用户"
                    visible={this.state.addUserModalShow}
                    onCancel={this.addUserModalHide}
                    onOk={this.addUser}
                    maskClosable={false}
                    cancelText="取消"
                    okText="确定"
                >
                    <JiraUserSelector onChange={user => {
                        this.props.addUser({ name: user.name, nickname: user.nickname, password: user.password }).then(data => {
                            this.setState({
                                name: '',
                                nickname: '',
                                password_confirm: '',
                                password: '',
                                addUserModalShow: false
                            },
                                message.info('添加成功')
                            )
                        });
                    }}/>
                </Modal>
                : <Modal
                    title="添加用户"
                    visible={this.state.addUserModalShow}
                    onCancel={this.addUserModalHide}
                    onOk={this.addUser}
                    maskClosable={false}
                    cancelText="取消"
                    okText="确定"
                >
                    <Form
                    >
                        <FormItem {...formItemLayout} label="用户名" required>
                            <Input type="text" value={name} onChange={(e) => this.changeValue(e, 'name')} required />
                        </FormItem>
                        <FormItem {...formItemLayout} label="昵称" required>
                            <Input type="text" value={nickname} onChange={(e) => this.changeValue(e, 'nickname')} required />
                        </FormItem>
                        {store.usePasswordChange && 
                            <FormItem {...formItemLayout} label="密码" required>
                                <Input type="password" maxLength={16} placeholder="密码长度8-16，需包含大小写字母及数字" value={password} onChange={(e) => this.changeValue(e, 'password')} required />
                            </FormItem>
                        }
                        {store.usePasswordChange && 
                            <FormItem {...formItemLayout} label="确认密码" required>
                                <Input type="password" maxLength={16} placeholder="密码长度8-16位，需包含大小写字母及数字" value={password_confirm} onChange={(e) => this.changeValue(e, 'password_confirm')} required />
                            </FormItem>
                        }
                    </Form>
                </Modal>
            }
            
        </div>
    }

    addUser = (e) => {
        e.preventDefault();
        const { name, nickname, password, password_confirm } = this.state;
        const {users} = this.props
        let userNames = users.map(i=>i.name)
        if (name.length === 0 || nickname.length === 0) {
            message.warning('请完善用户信息')
            return false;
        }
        if (userNames.includes(name)) {
            message.warning('用户名已存在，请重新输入')
            return false;
        }
        if (store.usePasswordChange) {
            if (!reg_password.test(password)){
                message.warning('密码需包含大小写字母及数字8-16位，请重新输入')
                return false;
            }
            if (password !== password_confirm) {
                message.warning('两次密码输入不一致，请重新输入')
                this.setState({
                    password_confirm: '',
                    password: ''
                });
                return false;
            }
        }
        this.props.addUser({ name: name, nickname: nickname, password: password }).then(data => {
            this.setState({
                name: '',
                nickname: '',
                password_confirm: '',
                password: '',
                addUserModalShow: false
            },
                message.info('添加成功')
            )
        });
    }

    delUser = (userId: string | number) => {
        confirm({
            icon: <ExclamationCircleOutlined />,
            content: "确定要删除该用户吗?",
            onOk: () => {
                this.props.delUser(userId);
            },
            cancelText: "取消",
            okText: "确定"
        });
    }
    resetPassword = (userId: string | number) => {
        prompt({
            title: '重置用户密码',
            invalid_message: (v) => reg_password.test(v) ? '' : '密码需包含大小写字母及数字8-16位，请重新输入',
            value: create_password()
        }).then((value) => {
            this.props.resetPassword(userId, value);
        })
    }

    updateUserRole = (e, userId: string | number) => {
        let roleId = e;
        this.props.updateUserRole({ userId: userId, roleId: roleId });
    }
        
    updateUserLockIPs = (userId: string | number) => (e: any) => {
        this.props.updateUserLockIPs({
            userId, ips: e.target['value']
        })
    }
    updateUserExpires = (userId: string | number) => (expires: number) => {
        this.props.updateUserExpires({
            userId, expires
        })
    }

    changeValue = (e, prop) => {
        this.setState({
            [prop]: e.target.value.replace(/(^\s*)|(\s*$)/g, "")
        } as any)
    }

    trim = (str: string) => {
        return str.replace(/(^\s*)|(\s*$)/g, "");
    }

    addUserModalOnShow = () => {
        this.setState({
            addUserModalShow: true
        })
    }

    addUserModalHide = () => {
        this.setState({
            addUserModalShow: false
        })
    }
}